package com.mysoft.gfyx.marketdevelop.mip.dto;

import com.mysoft.framework.modeling.dto.Filter;
import com.mysoft.gfyx.marketdevelop.mip.dto.TjTag.TagFilter;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Data
public class GetDeveloperFilterDataRequestDto extends GetDeveloperDataRequestDto {
    private ArrayList<BaseTjFilterDto> filters;

    private String detail_table_name;

    private int page;

    private int page_size;
    // 1 presto 2 sr
    private int query_engine;
//    private int query_engine = 1;

    private ArrayList<String> tag_ids;

    private ArrayList<TagFilter> tag_filters;

    private ArrayList<GetDeveloperFieldMapDto> table_field_maps;

    private ArrayList<GetDeveloperSortDto> sorts;

    public GetDeveloperFilterDataRequestDto() {
        this.filters = new ArrayList<>();
    }

    public void addFilterDtos(String field, int operate, Object value, String tableName, int associate) {
        if (value == null) {
            return;
        }
        BaseTjFilterDto dto = new BaseTjFilterDto();
        dto.setAttribute_name(field);
        dto.setOperate(operate);
        dto.setValue(value);
        dto.setTable_name(tableName);
        dto.setAssociate_previous(associate);
        this.filters.add(dto);
    }

    /**
     * 只支持一个表的搜索
     * @param filters
     * @param tableName
     */
    public void addFilterByLoadDataApi(List<Filter> filters, String tableName, Map<String, String> tableNameMap) {
        if (filters == null || filters.size() == 0) {
            return;
        }

        filters.forEach(filter -> {
            BaseTjFilterDto dto = new BaseTjFilterDto();
            if (this.filters.size() > 0) {
                dto.setAssociate_previous(BaseTjFilterDto.ASSOCIATE_AND);
            } else {
                dto.setAssociate_previous(BaseTjFilterDto.ASSOCIATE_NONE);
            }

            int subRelation = "and".equals(filter.getType()) ? BaseTjFilterDto.ASSOCIATE_AND : BaseTjFilterDto.ASSOCIATE_OR;
            ArrayList<BaseTjFilterDto> subFilters = new ArrayList<>();
            filter.getCondition().forEach(condition -> {
                int tjCondition = this.convertSqlConditionToTjCondition(condition.getOperatorType());
                Object tjValue = this.convertSqlValueToTjValue(condition.getOperatorType(), condition.getValue());

                BaseTjFilterDto lv2Dto = new BaseTjFilterDto();
                lv2Dto.setAttribute_name(condition.getField());
                lv2Dto.setOperate(tjCondition);
                lv2Dto.setValue(tjValue);
                String searchTableName = tableNameMap.getOrDefault(condition.getField(), tableName);
                lv2Dto.setTable_name(searchTableName);
                if (subFilters.size() > 0) {
                    lv2Dto.setAssociate_previous(subRelation);
                } else {
                    lv2Dto.setAssociate_previous(BaseTjFilterDto.ASSOCIATE_NONE);
                }

                subFilters.add(lv2Dto);
            });
            dto.setSub_filter(subFilters);

            this.filters.add(dto);
        });
    }

    public void addFilterByLoadDataApi(List<Filter> filters, String tableName) {
        Map<String, String> tableNameMap = new HashMap<>();
        addFilterByLoadDataApi(filters, tableName, tableNameMap);
    }

    protected int convertSqlConditionToTjCondition(String condition) {
        int tjCondition;
        switch (condition) {
            case "gt":
                tjCondition = BaseTjFilterDto.OPERATE_LARGER;
                break;
            case "lt":
                tjCondition = BaseTjFilterDto.OPERATE_LESS;
                break;
            case "ge":
                tjCondition = BaseTjFilterDto.OPERATE_LARGER_EQUAL;
                break;
            case "le":
                tjCondition = BaseTjFilterDto.OPERATE_LESS_EQUAL;
                break;
            case "eq":
                tjCondition = BaseTjFilterDto.OPERATE_EQUAL;
                break;
            case "like":
                tjCondition = BaseTjFilterDto.OPERATE_LIKE;
                break;
            case "in":
                tjCondition = BaseTjFilterDto.OPERATE_CONTAIN;
                break;
            default:
                tjCondition = BaseTjFilterDto.OPERATE_EQUAL;
        }
        return tjCondition;
    }

    protected Object convertSqlValueToTjValue(String condition, Object value) {
        Object tjValue;
        switch (condition) {
            case "in":
                if (value instanceof ArrayList) {
                    tjValue = StringUtils.join((ArrayList<?>) value, ",");
                } else {
                    tjValue = value;
                }
                break;
            default:
                tjValue = this.convertObjectToString(value);
        }
        return tjValue;
    }

    protected String convertObjectToString(Object v) {
        return String.valueOf(v);
    }
}
